package com.bolt.auth.security.auth.server.component;

import com.bolt.auth.security.common.model.AuthUserDetails;
import com.bolt.common.security.RSAUtil;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Created by Administrator on 2020/12/1.
 */

public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {




    private final UserDetailsService userService;

    private final PasswordEncoder passwordEncoder;

    private final String  rsaKey;

    //, CaptchaService captchaService, boolean passwordCaptcha
    public CustomAuthenticationProvider(UserDetailsService userService, PasswordEncoder passwordEncoder,String rsaKey) {
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
        this.rsaKey = rsaKey;
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                  UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            this.logger.debug("Authentication failed: no credentials provided");
            throw new UsernameNotFoundException("用户不存在");
        } else {
            AuthUserDetails authUserDetails = (AuthUserDetails)userDetails;
            String password;
            try{
                 password = RSAUtil.decryptByPrivateKey(rsaKey,authentication.getCredentials().toString());
            }catch (Exception ex ){
                throw new BadCredentialsException("解密失败");
            }
            String presentedPassword = "{" + authUserDetails.getAuthSalt() + "}" + password;
            if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
                this.logger.debug("Authentication failed: password does not match stored value");
                throw new BadCredentialsException("用户名或密码错误");
            }
        }
    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {

        // 添加额外处理，如验证码等
        try {
            UserDetails loadedUser = userService.loadUserByUsername(username);
            if (loadedUser == null) {
                throw new UsernameNotFoundException("用户不存在");
            }

            return loadedUser;
        } catch (UsernameNotFoundException | InternalAuthenticationServiceException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new InternalAuthenticationServiceException(ex.getMessage(), ex);
        }
    }

    @Override
    public boolean supports(Class <?> arg0) {
        return true;
    }
}

 